package com.cg.service.impl;

import com.cg.common.AutoFillConstant;
import com.cg.common.BaseContext;
import com.cg.dto.RegisterDTO;
import com.cg.dto.UserDTO;
import com.cg.entity.DictPositionKeyword;
import com.cg.entity.Region;
import com.cg.entity.User;
import com.cg.entity.UserPositionKeyword;
import com.cg.mapper.DictPositionKeywordMapper;
import com.cg.mapper.UserMapper;
import com.cg.mapper.UserPositionKeywordMapper;
import com.cg.service.RegionService;
import com.cg.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * 用户服务实现类
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private DictPositionKeywordMapper dictPositionKeywordMapper;
    
    @Autowired
    private UserPositionKeywordMapper userPositionKeywordMapper;
    
    @Autowired
    private RegionService regionService;
    
    /**
     * 用户注册
     * @param registerDTO 注册信息
     */
    @Override
    @Transactional
    public void register(RegisterDTO registerDTO) {
        log.info("开始用户注册，注册信息：{}", registerDTO);
        
        // 1. 生成用户名（user_前缀 + 时间戳）
        String username = "user_" + System.currentTimeMillis();
        
        // 2. 创建用户实体
        User user = new User();
        
        // 3. 设置基本信息
        user.setUsername(username);
        user.setPassword(DigestUtils.md5DigestAsHex(AutoFillConstant.DEFAULT_PASSWORD.getBytes()));
        user.setNickName(registerDTO.getNickname() != null ? registerDTO.getNickname() : username);
        user.setEmail(registerDTO.getEmail());
        user.setAge(registerDTO.getAge());
        user.setSex(null); // 注册时暂不设置性别
        // 处理地址信息
        String fullAddress = buildFullAddress(registerDTO);
        user.setAddress(fullAddress);
        user.setExpectedAddress(fullAddress);
        user.setTargetPosition(registerDTO.getIdealKeywords());
        
        // 4. 处理薪资范围
        if (registerDTO.getSalaryRange() != null && !registerDTO.getSalaryRange().isEmpty()) {
            String[] salaryParts = registerDTO.getSalaryRange().split("-");
            if (salaryParts.length == 2) {
                try {
                    String minSalary = salaryParts[0].replaceAll("[^0-9]", "");
                    String maxSalary = salaryParts[1].replaceAll("[^0-9]", "");
                    user.setExpectedSalaryMin(Integer.parseInt(minSalary));
                    user.setExpectedSalaryMax(Integer.parseInt(maxSalary));
                } catch (NumberFormatException e) {
                    log.warn("薪资范围解析失败：{}", registerDTO.getSalaryRange());
                }
            }
        }
        
        // 5. 设置状态和时间
        user.setStatus(AutoFillConstant.USER_STATUS_ENABLE);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        
        // 6. 保存用户
        userMapper.insert(user);
        log.info("用户保存成功，用户ID：{}", user.getId());
        
        // 7. 处理岗位关键词
        if (registerDTO.getIdealKeywords() != null && !registerDTO.getIdealKeywords().isEmpty()) {
            List<String> keywords = Arrays.asList(registerDTO.getIdealKeywords().split(","));
            
            for (String keywordName : keywords) {
                keywordName = keywordName.trim();
                if (!keywordName.isEmpty()) {
                    // 查询关键词是否存在
                    DictPositionKeyword keyword = dictPositionKeywordMapper.getByName(keywordName);
                    if (keyword != null) {
                        // 创建用户关键词关系
                        UserPositionKeyword userKeyword = new UserPositionKeyword();
                        userKeyword.setUserId(user.getId());
                        userKeyword.setKeywordId(keyword.getId());
                        userPositionKeywordMapper.insert(userKeyword);
                    } else {
                        log.warn("关键词不存在：{}", keywordName);
                    }
                }
            }
        }
        
        log.info("用户注册完成，用户ID：{}，用户名：{}", user.getId(), user.getUsername());
    }
    
    /**
     * 用户登录
     * @param username 用户名
     * @param password 密码
     * @return 用户信息
     */
    @Override
    public UserDTO login(String username, String password) {
        log.info("用户登录，用户名：{}", username);
        
        // 根据用户名查询用户
        User user = userMapper.getByUsername(username);
        if (user == null) {
            log.warn("用户不存在：{}", username);
            return null;
        }
        
        // 验证密码
        String encryptedPassword = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!user.getPassword().equals(encryptedPassword)) {
            log.warn("密码错误，用户名：{}", username);
            return null;
        }
        
        // 检查用户状态
        if (user.getStatus() != null && user.getStatus() == AutoFillConstant.USER_STATUS_DISABLE) {
            log.warn("用户已被禁用，用户名：{}", username);
            return null;
        }
        
        // 转换为DTO
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);
        
        log.info("用户登录成功：{}", username);
        return userDTO;
    }
    
    /**
     * 根据用户名查询用户
     * @param username 用户名
     * @return 用户信息
     */
    @Override
    public UserDTO getUserByUsername(String username) {
        User user = userMapper.getByUsername(username);
        if (user != null) {
            UserDTO userDTO = new UserDTO();
            BeanUtils.copyProperties(user, userDTO);
            return userDTO;
        }
        return null;
    }
    
    /**
     * 根据邮箱查询用户
     * @param email 邮箱
     * @return 用户信息
     */
    @Override
    public UserDTO getUserByEmail(String email) {
        User user = userMapper.getByEmail(email);
        if (user != null) {
            UserDTO userDTO = new UserDTO();
            BeanUtils.copyProperties(user, userDTO);
            return userDTO;
        }
        return null;
    }
    
    /**
     * 根据ID查询用户
     * @param id 用户ID
     * @return 用户信息
     */
    @Override
    public UserDTO getUserById(Long id) {
        User user = userMapper.getById(id);
        if (user != null) {
            UserDTO userDTO = new UserDTO();
            BeanUtils.copyProperties(user, userDTO);
            return userDTO;
        }
        return null;
    }
    
    /**
     * 用户注册（旧版本，兼容性）
     * @param userDTO 用户信息
     * @return 是否成功
     */
    @Override
    @Transactional
    public boolean register(UserDTO userDTO) {
        try {
            log.info("旧版本注册，用户名：{}", userDTO.getUsername());
            
            // 检查用户名是否已存在
            if (existsByUsername(userDTO.getUsername())) {
                log.warn("用户名已存在：{}", userDTO.getUsername());
                return false;
            }
            
            // 检查邮箱是否已存在
            if (userDTO.getEmail() != null && existsByEmail(userDTO.getEmail())) {
                log.warn("邮箱已存在：{}", userDTO.getEmail());
                return false;
            }
            
            // 创建用户实体
            User user = new User();
            BeanUtils.copyProperties(userDTO, user);
            
            // 设置密码
            user.setPassword(DigestUtils.md5DigestAsHex(userDTO.getPassword().getBytes()));
            
            // 设置状态和时间
            user.setStatus(AutoFillConstant.USER_STATUS_ENABLE);
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            
            // 保存用户
            userMapper.insert(user);
            
            log.info("旧版本注册成功，用户ID：{}", user.getId());
            return true;
            
        } catch (Exception e) {
            log.error("旧版本注册失败", e);
            return false;
        }
    }
    
    /**
     * 检查用户名是否存在
     * @param username 用户名
     * @return 是否存在
     */
    @Override
    public boolean existsByUsername(String username) {
        User user = userMapper.getByUsername(username);
        return user != null;
    }
    
    /**
     * 检查邮箱是否存在
     * @param email 邮箱
     * @return 是否存在
     */
    @Override
    public boolean existsByEmail(String email) {
        User user = userMapper.getByEmail(email);
        return user != null;
    }
    
    /**
     * 构建完整地址
     * @param registerDTO 注册信息
     * @return 完整地址
     */
    private String buildFullAddress(RegisterDTO registerDTO) {
        StringBuilder address = new StringBuilder();
        
        // 如果有省份代码，获取省份名称
        if (registerDTO.getProvinceCode() != null && !registerDTO.getProvinceCode().isEmpty()) {
            Region province = regionService.getByCode(registerDTO.getProvinceCode());
            if (province != null) {
                address.append(province.getName());
            }
        }
        
        // 如果有城市代码，获取城市名称
        if (registerDTO.getCityCode() != null && !registerDTO.getCityCode().isEmpty()) {
            Region city = regionService.getByCode(registerDTO.getCityCode());
            if (city != null) {
                if (address.length() > 0) {
                    address.append(" ");
                }
                address.append(city.getName());
            }
        }
        
        // 如果有区县代码，获取区县名称
        if (registerDTO.getDistrictCode() != null && !registerDTO.getDistrictCode().isEmpty()) {
            Region district = regionService.getByCode(registerDTO.getDistrictCode());
            if (district != null) {
                if (address.length() > 0) {
                    address.append(" ");
                }
                address.append(district.getName());
            }
        }
        
        // 如果有自定义地址，添加到末尾
        if (registerDTO.getExpectedLocation() != null && !registerDTO.getExpectedLocation().isEmpty()) {
            if (address.length() > 0) {
                address.append(" ");
            }
            address.append(registerDTO.getExpectedLocation());
        }
        
        return address.toString();
    }
}

